package com.carl.zeus.server.system;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.carl.zeus.common.constant.BusinessCode;
import com.carl.zeus.common.constant.BusinessConstants;
import com.carl.zeus.common.constant.BusinessMsg;
import com.carl.zeus.common.util.BusinessMsgUtil;
import com.carl.zeus.common.util.ParseObjectUtils;
import com.carl.zeus.config.shiro.ShiroService;
import com.carl.zeus.dao.system.SysMenuMapper;
import com.carl.zeus.dao.system.SysRoleMapper;
import com.carl.zeus.dao.system.SysRoleMenuMapper;
import com.carl.zeus.dao.system.SysUserRoleMapper;
import com.carl.zeus.model.system.SysMenu;
import com.carl.zeus.model.system.SysRole;
import com.carl.zeus.model.system.SysRoleMenu;
import com.carl.zeus.model.system.SysUserRole;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.tio.json.Json;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zcm
 * @since 2017-02-10
 */
@Service
public class SysRoleService extends ServiceImpl<SysRoleMapper, SysRole> {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private ShiroService shiroService;

    public List<SysRole> listAjax(int page, int limit, String key, String value) {
        List<SysRole> roleList = sysRoleMapper.selectPage(
                new Page<SysRole>(page, limit),
                new EntityWrapper<SysRole>().like(key, value));
        return roleList;
    }

    public Object countRoleList() {
        return sysRoleMapper.selectCount(new EntityWrapper<>());
    }

    /**
     * 根据roleId查询角色资源信息
     * @param roleId 角色Id
     * @return
     */
    public SysRole selectRoleMenuByRoleId(Long roleId){

        StringBuilder sb = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();

        if(null != roleId){
            SysRole role = sysRoleMapper.selectById(roleId);
            List<SysRoleMenu> roleRes =  sysRoleMenuMapper.selectRoleMenuByRoleId(roleId);
            if(null != roleRes && !roleRes.isEmpty()){
                for (SysRoleMenu r : roleRes) {
                    SysMenu menu = sysMenuMapper.selectById(r.getMenuId());
                    if(menu != null){
                        //取得当前角色所属资源的ID以逗号拼接
                        sb.append(menu.getId()).append(",");
                        //取得当前角色所属资源的名称以逗号拼接
                        sb2.append(menu.getName()).append(",");
                    }
                }
                //将拼接后的资源信息的最后一个逗号删除
                if(sb.length() >0){
                    sb.deleteCharAt(sb.length() - 1);
                }
                if(sb2.length() >0){
                    sb2.deleteCharAt(sb2.length() - 1);
                }
            }

            //赋给角色实体,方便页面显示
            role.setMenuNames(sb2.toString());
            role.setMenuIds(sb.toString());
            return role;
        }
        return null;
    }

    /**
     * 保存角色信息授权信息
     * @param roleId        角色Id
     * @param menuIds    资源Id数组
     * @return
     * @throws Exception
     */
    @Transactional
    public BusinessMsg saveOrUpdateSysRoleMenu(Long roleId, Long [] menuIds) throws Exception {
        try {
            if (null != menuIds && menuIds.length > 0) {

                List<SysRoleMenu> roleMenus  = sysRoleMenuMapper.selectRoleMenuByRoleId(roleId);
                // 先删除之前的角色菜单关系
                if(null != roleMenus && !roleMenus.isEmpty()){
                    for (SysRoleMenu roleMenu : roleMenus) {
                        sysRoleMenuMapper.deleteById(roleMenu.getId());
                    }
                }
                for (Long menuId : menuIds) {
                    //保存角色菜单信息
                    SysRoleMenu roleMenu = new SysRoleMenu();
                    roleMenu.setRoleId(roleId);
                    roleMenu.setMenuId(menuId);
                    sysRoleMenuMapper.insert(roleMenu);
                }
            } else{
                //如果资源Id为空，则清空当前角色所有的菜单资源信息
                sysRoleMenuMapper.deleteRoleMenuByRoleId(roleId);
            }
            // 清空用户权限缓存信息
            shiroService.clearAllCacheAuth();
        } catch (Exception e) {
            throw e;
        } finally {
        }
        return BusinessMsgUtil.returnCodeMessage(BusinessCode.GLOBAL_SUCCESS);
    }

    /**
     * 批量角色状态失效
     * @param roleIds	角色Id
     * @return
     * @throws Exception
     */
    public BusinessMsg updateRoleBatchStatus(Long[] roleIds) {
        try {
            if(null != roleIds && roleIds.length > 0){
                for (Long roleId : roleIds) {
                    //解除用户与角色绑定关系
                    sysUserRoleMapper.deleteUserRoleByRoleId(roleId);
                    //解除角色与菜单绑定关系
                    sysRoleMenuMapper.deleteRoleMenuByRoleId(roleId);

                    //更改角色状态为0-失效
                    Map<String, Object> params = new HashMap<>();
                    params.put("status", BusinessConstants.SYS_ROLE_STATUS_0.getCode());
                    params.put("id", roleId);
                    sysRoleMapper.updateRoleByStatus(params);
                }
                // 清空用户权限缓存信息
                shiroService.clearAllCacheAuth();
            }

        } catch (Exception e) {
            throw e;
        }finally {
        }
        return BusinessMsgUtil.returnCodeMessage(BusinessCode.GLOBAL_SUCCESS);
    }

    /**
     * 角色状态失效
     * @param roleId	角色Id
     * @return
     * @throws Exception
     */
    @Transactional
    public BusinessMsg updateRoleStatus(Long roleId) {
        try {
            //解除用户与角色绑定关系
            sysUserRoleMapper.deleteUserRoleByRoleId(roleId);
            //解除角色与菜单绑定关系
            sysRoleMenuMapper.deleteRoleMenuByRoleId(roleId);

            //更改角色状态为0-失效
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("status", BusinessConstants.SYS_ROLE_STATUS_0.getCode());
            params.put("id", roleId);
            sysRoleMapper.updateRoleByStatus(params);
            // 清空用户权限缓存信息
            shiroService.clearAllCacheAuth();
        } catch (Exception e) {
            throw e;
        }finally {
        }
        return BusinessMsgUtil.returnCodeMessage(BusinessCode.GLOBAL_SUCCESS);
    }

    /**
     * 查询状态为有效,待分配的角色信息(用以用户分配角色时显示)
     * @param roleIds 已分配角色Id,以逗号分割
     */
    public String selectUserRoleByRoleIdList(String roleIds){
        Map<String, Object> map = new HashMap<>();
        //如果已给用户分配角色,则待分配用户显示栏中去除已分配的角色信息
        if(StringUtils.isNotEmpty(roleIds)){
            Long[] roleId = ParseObjectUtils.strArrayToIntArray(roleIds);
            List<SysRole> lists = sysRoleMapper.selectUserRoleByRoleIdList(roleId);
            map.put("rows", lists);
            return Json.toJson(map);
        }
        map.put("rows", sysRoleMapper.selectRoleListByStatus());
        //没有给用户分配角色,待分配显示栏中显示所有角色信息
        return Json.toJson(map);
    }

    /**
     * 查询状态为有效,已分配的角色信息(用已用户分配角色显示)
     * @param roleIds 角色Id
     * @return
     */
    public String selectDeceasedUserRoleByRoleIdList(String roleIds) {
        Map<String, Object> map = new HashMap<>();
        //没有给用户分配角色，则已分配角色列表为空
        if(StringUtils.isNotEmpty(roleIds)){
            Long[] roleId = ParseObjectUtils.strArrayToIntArray(roleIds);
            List<SysRole> lists = sysRoleMapper.selectDeceasedUserRoleByRoleIdList(roleId);
            map.put("rows", lists);
            return Json.toJson(map);
        }
        return null;
    }

    /**
     * 保存用户分配角色信息
     * @param userId 用户id
     * @param roleIds 分配的角色信息
     * @return
     * @throws Exception
     */
    @Transactional
    public BusinessMsg saveUserRole(Long userId, String roleIds) {
        try {
            List<SysUserRole> userRoles = sysUserRoleMapper.selectUserRolesListByUserId(userId);
            //如果角色Id不为空插入用户角色信息，否则删除用户下所有分配的角色
            if (StringUtils.isNotEmpty(roleIds)) {
                if (null != userRoles && !userRoles.isEmpty()) {
                    for (SysUserRole userRole : userRoles) {
                        sysUserRoleMapper.deleteById(userRole.getId());
                    }
                }
                for (String roleId : roleIds.split(",")) {
                    SysUserRole ur = new SysUserRole();
                    ur.setUserId(userId);
                    ur.setRoleId(Long.valueOf(roleId));
                    sysUserRoleMapper.insert(ur);
                }

            } else {
                if (null != userRoles && !userRoles.isEmpty()) {
                    for (SysUserRole userRole : userRoles) {
                        sysUserRoleMapper.deleteById(userRole.getId());
                    }
                }
            }
            // 清空用户权限缓存信息
            shiroService.clearAllCacheAuth();
        } catch (Exception e) {
            throw e;
        }finally {
        }
        return BusinessMsgUtil.returnCodeMessage(BusinessCode.GLOBAL_SUCCESS);
    }

}
